using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Windows;
using System.Xml;
using System.Windows.Forms;
using System.Drawing;

namespace Deduplicator
{

    class ResourceFileReader
    {
        private SortedDictionary<Int64, string> fileList = new SortedDictionary<Int64, string>(); 
        private SortedDictionary<Int64, string> doubleList = new SortedDictionary<Int64, string>(); 
        private Label lblfilesScanned;
        private Label lblitemsFound;
        private Label lblmemo;
        private PictureBox picturebox;
        private TreeView treeview;

        private ProgressBar progressBar;
        public int fileCount = 0;
        public int filesDone = 0;

        public ListBox.SelectedObjectCollection SelectedItems { get; set; }

        public ResourceFileReader(Label lblFilesScanned, Label lblItemsFound, Label lblMemo, ProgressBar progressbar, PictureBox pictureBox, TreeView treeView)
        {
            lblfilesScanned = lblFilesScanned;
            lblitemsFound = lblItemsFound;
            lblmemo = lblMemo;
            progressBar = progressbar;
            treeview = treeView;
            picturebox = pictureBox;
        }

        public void ScanDirectory(TreeNode Node)
        {
            if (File.Exists(Node.Name))
                ProcessFile(Node.Name);
            else if (Directory.Exists(Node.Name))
            {
                string text = GetCurrentFolder(Node.Name);

                Node.BackColor = Color.Red;
                ProcessDirectory(Node.Name);
                Node.BackColor = Color.White;
            }
        }

        public string GetCurrentFolder(string Subdirectory)
        {
            string[] fileparts = Subdirectory.Split('\\');
            if (fileparts.Length > 1)
                return fileparts[fileparts.Length - 1];
            else
                return "";
        }
        
        public int CountFiles(TreeNode Node)
        {
            try
            {
                filesDone += 1;
          
                if (filesDone % 100 == 0)
                {
                    lblfilesScanned.Text = filesDone.ToString();
                    lblfilesScanned.Update();
                    lblmemo.Text = "Scanning " + Node.Name;
                    lblmemo.Update();
                }

                string[] fileEntries = Directory.GetFiles(Node.Name);
                foreach (string fileName in fileEntries)
                    fileCount += 1;

                string[] subdirectoryEntries = Directory.GetDirectories(Node.Name);

                foreach (string subdirectory in subdirectoryEntries)
                    CountFiles(Node.Nodes.Add(subdirectory, GetCurrentFolder(subdirectory)));
            }
            catch
            { 
                lblmemo.Text = "Cannot acces " + Node.Name;
                lblmemo.Update();
            }
            return fileCount;
        }
         
        public void ProcessDirectory(string targetDirectory)
        {

            lblmemo.Text = targetDirectory;
            lblmemo.Update();
            try
            {
                string[] fileEntries = Directory.GetFiles(targetDirectory);
                foreach (string fileName in fileEntries)
                    ProcessFile(fileName);

                string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
                foreach (string subdirectory in subdirectoryEntries)
                    ProcessDirectory(subdirectory);
            }
            catch
            {
                lblmemo.Text = "Cannot acces " + targetDirectory;
                lblmemo.Update();
            }
        }


        public Int64 GetFileIdentifier(FileStream fs)
        {
            Int64 fileIdentifier = 0;
            long jumpSize = fs.Length / 9; 
            byte[] B = new byte[1];
            fs.Seek(0, SeekOrigin.Begin);

            for(int i = 0; i < 7; i++)
            {
                fs.Seek(jumpSize, SeekOrigin.Current);
                fs.Read(B, 0,1);
                fileIdentifier += 256 * fileIdentifier + B[0];
            }
            return fileIdentifier;
        }

        public bool ThumbnailCallback()
        {
            return false;
        }

        public void DrawThumbnail(FileStream f)
        {
            Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
            Bitmap myBitmap = new Bitmap(f);
            picturebox.Image = myBitmap.GetThumbnailImage(128, 128, myCallback, IntPtr.Zero);
            picturebox.Image.GetThumbnailImage(128, 128, myCallback, IntPtr.Zero);
            picturebox.Update();
        }


        public bool FileIsRelevant(string fileName)
        {
            if (SelectedItems.Contains("All")) return true;
            else
            {
                bool IsRelevant = false;
                for (int i = 0; i < SelectedItems.Count; i++)
                {
                    string Extension = SelectedItems[i].ToString();
                    IsRelevant = fileName.Contains(Extension);
                    if (IsRelevant) break;
                }
                return IsRelevant;
            }
        }

        public void CopyFiles(string DestinationFolder)
        {
            for (int i = 0; i < fileList.Count; i++)
            {

                FileStream f = new FileStream(fileList[i], FileMode.Open);
                DateTime d = System.IO.File.GetCreationTime(fileList[i]);
                string newFileName = DestinationFolder + d.Year + "-" + d.Month + "\\" + fileList[i];

           }
        }

        public void ProcessFile(string fileName)
        {
            filesDone += 1;


            progressBar.Value = (filesDone * 100) / fileCount;
            progressBar.Update();

            if (filesDone % 10 == 0)
            {
                lblfilesScanned.Text = filesDone.ToString();
                lblfilesScanned.Update();

            };
            
            if (FileIsRelevant(fileName))
            {
                try
                {
                    FileStream f = new FileStream(fileName, FileMode.Open);
                    Int64 identifier = GetFileIdentifier(f);

                    if (filesDone % 10 == 0)
                    {
                        if (fileName.Contains(".jpg"))
                            DrawThumbnail(f);
                    }

                    if (fileList.ContainsKey(identifier))
                    {
                        int d = Convert.ToInt32(lblitemsFound.Text) + 1;
                        lblitemsFound.Text = d.ToString();
                        lblitemsFound.Update();
                    }
                    else
                        fileList.Add(identifier, fileName);
                    f.Dispose();
                }
                catch 
                {
                    lblmemo.Text = "Cannot scan " + fileName;
                    lblmemo.Update();
                }
            }
        }
    }
                                         
        
    
}
